# -*- coding:utf-8 -*-

from fastapi import APIRouter, Depends, Request
from sqlalchemy.ext.asyncio import AsyncSession
from module_admin.aspect.interface_auth import CheckUserInterfaceAuth
from module_admin.annotation.log_annotation import Log
from module_admin.service.agent_client_service import AgentClientService
from module_admin.entity.vo.agent_client_vo import (
    AgentClientModel,
    AgentClientQueryModel,
    AgentClientCreateModel,
    AgentClientUpdateModel,
    AgentClientCommandModel,
    AgentAssignModel
)
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.login_service import LoginService
from config.get_db import get_db
from config.enums import BusinessType
from utils.response_util import ResponseUtil
from utils.page_util import PageResponseModel
from utils.log_util import logger

agentClientController = APIRouter(prefix='/agent/client', tags=['Agent客户端管理'])


@agentClientController.get(
    '/list',
    response_model=PageResponseModel,
    dependencies=[Depends(CheckUserInterfaceAuth('agent:client:list'))]
)
async def get_client_list(
    request: Request,
    client_query: AgentClientQueryModel = Depends(AgentClientQueryModel),
    page_num: int = 1,
    page_size: int = 10,
    db: AsyncSession = Depends(get_db),
    current_user: CurrentUserModel = Depends(LoginService.get_current_user)
):
    """获取客户端列表（支持权限过滤）"""
    try:
        # 判断是否是管理员（role_id=1）
        role_id_list = [role.role_id for role in current_user.user.role]
        is_admin = 1 in role_id_list
        
        # 获取当前用户ID
        current_user_id = current_user.user.user_id
        
        result = await AgentClientService.get_client_list(
            db, client_query, page_num, page_size, current_user_id, is_admin
        )
        return ResponseUtil.success(model_content=result)
    except Exception as e:
        logger.exception(e)
        return ResponseUtil.error(msg=str(e))


@agentClientController.get(
    '/{client_id}',
    response_model=AgentClientModel,
    dependencies=[Depends(CheckUserInterfaceAuth('agent:client:query'))]
)
async def get_client_detail(
    request: Request,
    client_id: int,
    db: AsyncSession = Depends(get_db)
):
    """获取客户端详情"""
    try:
        client = await AgentClientService.get_client_detail(db, client_id)
        if client:
            return ResponseUtil.success(model_content=client)
        return ResponseUtil.error(msg='客户端不存在')
    except Exception as e:
        logger.exception(e)
        return ResponseUtil.error(msg=str(e))


@agentClientController.post(
    '/add',
    dependencies=[Depends(CheckUserInterfaceAuth('agent:client:add'))]
)
@Log(title='Agent客户端管理', business_type=BusinessType.INSERT, log_type='operation')
async def add_client(
    request: Request,
    create_data: AgentClientCreateModel,
    db: AsyncSession = Depends(get_db)
):
    """添加客户端"""
    try:
        # 从请求中获取当前用户信息
        current_user = request.state.user
        
        client = await AgentClientService.create_client(
            db, create_data, current_user.user_id, current_user.dept_id
        )
        await db.commit()
        
        return ResponseUtil.success(msg='添加成功')
    except Exception as e:
        await db.rollback()
        logger.exception(e)
        return ResponseUtil.error(msg=str(e))


@agentClientController.put(
    '/{client_id}',
    dependencies=[Depends(CheckUserInterfaceAuth('agent:client:edit'))]
)
@Log(title='Agent客户端管理', business_type=BusinessType.UPDATE, log_type='operation')
async def update_client_by_id(
    request: Request,
    client_id: int,
    update_data: AgentClientUpdateModel,
    db: AsyncSession = Depends(get_db),
    current_user: CurrentUserModel = Depends(LoginService.get_current_user)
):
    """更新客户端信息（权限控制：只能修改分配给自己的agent）"""
    try:
        # ✅ 先获取agent信息
        client = await AgentClientService.get_client_detail(db, client_id)
        if not client:
            return ResponseUtil.error(msg='Agent不存在')
        
        # ✅ 检查是否有权操作此agent
        role_id_list = [role.role_id for role in current_user.user.role]
        is_admin = 1 in role_id_list
        
        has_permission = await AgentClientService.check_agent_access_permission(
            db, client.client_id, current_user.user.user_id, is_admin
        )
        
        if not has_permission:
            return ResponseUtil.error(msg='无权修改此Agent')
        
        # ✅ 执行更新
        await AgentClientService.update_client(db, client_id, update_data)
        await db.commit()
        
        return ResponseUtil.success(msg='更新成功')
    except Exception as e:
        await db.rollback()
        logger.exception(e)
        return ResponseUtil.error(msg=str(e))


@agentClientController.put(
    '/edit',
    dependencies=[Depends(CheckUserInterfaceAuth('agent:client:edit'))]
)
@Log(title='Agent客户端管理', business_type=BusinessType.UPDATE, log_type='operation')
async def edit_client(
    request: Request,
    client_id: int,
    update_data: AgentClientUpdateModel,
    db: AsyncSession = Depends(get_db),
    current_user: CurrentUserModel = Depends(LoginService.get_current_user)
):
    """编辑客户端（权限控制：只能修改分配给自己的agent）"""
    try:
        # ✅ 获取agent信息
        client = await AgentClientService.get_client_detail(db, client_id)
        if not client:
            return ResponseUtil.error(msg='Agent不存在')
        
        # ✅ 检查权限
        role_id_list = [role.role_id for role in current_user.user.role]
        is_admin = 1 in role_id_list
        
        has_permission = await AgentClientService.check_agent_access_permission(
            db, client.client_id, current_user.user.user_id, is_admin
        )
        
        if not has_permission:
            return ResponseUtil.error(msg='无权修改此Agent')
        
        await AgentClientService.update_client(db, client_id, update_data)
        await db.commit()
        
        return ResponseUtil.success(msg='更新成功')
    except Exception as e:
        await db.rollback()
        logger.exception(e)
        return ResponseUtil.error(msg=str(e))


@agentClientController.delete(
    '/remove/{client_id}',
    dependencies=[Depends(CheckUserInterfaceAuth('agent:client:remove'))]
)
@Log(title='Agent客户端管理', business_type=BusinessType.DELETE, log_type='operation')
async def remove_client(
    request: Request,
    client_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: CurrentUserModel = Depends(LoginService.get_current_user)
):
    """删除客户端（权限控制：只能删除分配给自己的agent）"""
    try:
        # ✅ 获取agent信息
        client = await AgentClientService.get_client_detail(db, client_id)
        if not client:
            return ResponseUtil.error(msg='Agent不存在')
        
        # ✅ 检查权限
        role_id_list = [role.role_id for role in current_user.user.role]
        is_admin = 1 in role_id_list
        
        has_permission = await AgentClientService.check_agent_access_permission(
            db, client.client_id, current_user.user.user_id, is_admin
        )
        
        if not has_permission:
            return ResponseUtil.error(msg='无权删除此Agent')
        
        await AgentClientService.delete_client(db, client_id)
        await db.commit()
        
        return ResponseUtil.success(msg='删除成功')
    except Exception as e:
        await db.rollback()
        logger.exception(e)
        return ResponseUtil.error(msg=str(e))


@agentClientController.put(
    '/remark/{client_id}',
    dependencies=[Depends(CheckUserInterfaceAuth('agent:client:edit'))]
)
async def update_remark(
    request: Request,
    client_id: str,
    remark: str = "",
    db: AsyncSession = Depends(get_db)
):
    """更新客户端备注"""
    try:
        # 根据client_id获取客户端
        from module_admin.dao.agent_client_dao import AgentClientDao
        client = await AgentClientDao.get_client_by_client_id(db, client_id)
        
        if not client:
            return ResponseUtil.error(msg='客户端不存在')
        
        # 更新备注
        client.remark = remark
        await db.commit()
        
        return ResponseUtil.success(msg='备注更新成功', data={'remark': remark})
    except Exception as e:
        await db.rollback()
        logger.exception(e)
        return ResponseUtil.error(msg=str(e))


@agentClientController.get(
    '/online/list',
    dependencies=[Depends(CheckUserInterfaceAuth('agent:client:list'))]
)
async def get_online_clients(
    request: Request,
    db: AsyncSession = Depends(get_db)
):
    """获取在线客户端列表"""
    try:
        clients = await AgentClientService.get_online_clients(db)
        return ResponseUtil.success(data=clients)
    except Exception as e:
        logger.exception(e)
        return ResponseUtil.error(msg=str(e))


@agentClientController.post(
    '/command/{client_id}',
    dependencies=[Depends(CheckUserInterfaceAuth('agent:client:command'))]
)
@Log(title='Agent客户端命令', business_type=BusinessType.OTHER, log_type='operation')
async def send_command(
    request: Request,
    client_id: str,
    command_data: AgentClientCommandModel,
    db: AsyncSession = Depends(get_db),
    current_user: CurrentUserModel = Depends(LoginService.get_current_user)
):
    """向客户端发送命令（权限控制：只能操作分配给自己的agent）"""
    try:
        # ✅ 检查是否有权操作此agent
        role_id_list = [role.role_id for role in current_user.user.role]
        is_admin = 1 in role_id_list
        
        has_permission = await AgentClientService.check_agent_access_permission(
            db, client_id, current_user.user.user_id, is_admin
        )
        
        if not has_permission:
            return ResponseUtil.error(msg='无权操作此Agent')
        
        # 导入TCP客户端管理器
        from tcp_server.tcp_clients import ClientManager
        
        # 获取客户端
        client = ClientManager.get_client_by_id(client_id)
        if not client:
            return ResponseUtil.error(msg='客户端未连接')
        
        # 发送命令
        message = {
            "event": command_data.command,
            "direction": "req",
            "data": command_data.data or {},
            "req_id": ""
        }
        
        success = await ClientManager.send_to_client(client_id, message)
        
        if success:
            return ResponseUtil.success(msg='命令已发送')
        else:
            return ResponseUtil.error(msg='发送失败')
            
    except Exception as e:
        logger.exception(e)
        return ResponseUtil.error(msg=str(e))


@agentClientController.post(
    '/assign',
    dependencies=[Depends(CheckUserInterfaceAuth('agent:client:assign'))]
)
@Log(title='Agent分配', business_type=BusinessType.UPDATE)
async def assign_clients(
    request: Request,
    assign_data: AgentAssignModel,
    db: AsyncSession = Depends(get_db),
    current_user: CurrentUserModel = Depends(LoginService.get_current_user)
):
    """分配agent给用户（管理员专用）"""
    try:
        # 验证是否是管理员
        role_id_list = [role.role_id for role in current_user.user.role]
        is_admin = 1 in role_id_list
        
        if not is_admin:
            return ResponseUtil.error(msg='只有管理员才能分配agent')
        
        # 执行分配（1对1分配：只接受单个user_id）
        user_id = assign_data.user_id if assign_data.user_id else None
        await AgentClientService.assign_clients_to_users(
            db, assign_data.client_ids, user_id
        )
        
        await db.commit()
        
        # ✅ 分配后更新client_user_map缓存
        try:
            from tcp_server.tcp_clients import ClientManager
            from module_admin.dao.agent_client_dao import AgentClientDao
            
            # 获取所有被分配的agent的client_id
            client_ids_to_refresh = []
            for agent_id in assign_data.client_ids:
                agent = await AgentClientDao.get_client_by_id(db, agent_id)
                if agent:
                    client_ids_to_refresh.append(agent.client_id)
            
            # 刷新缓存
            if client_ids_to_refresh:
                await ClientManager.refresh_client_user_map_by_client_ids(
                    request.app.state.db_session, 
                    client_ids_to_refresh
                )
                logger.info(f"✅ Agent分配后已更新client_user_map缓存: {len(client_ids_to_refresh)}个agent")
        except Exception as e:
            logger.error(f"更新client_user_map缓存失败: {e}", exc_info=True)
            # 不影响分配结果，只记录错误
        
        return ResponseUtil.success(msg='分配成功')
            
    except Exception as e:
        await db.rollback()
        logger.exception(e)
        return ResponseUtil.error(msg=str(e))

